class Ship extends GameObject
{
  float direction;
  float thrustAcc;
  float turnSpeed;
  float health;
  float energy;
  float maxHealth;
  float maxEnergy;
  int rad; //just so that the screen knows when the ship is off the screen
  float topSpeed;
  float mass;
  PShape shipShape;
  boolean firing;
  int firingCount;
  int firingDelay;
  boolean crashed;
  boolean getAlive(){return alive;}
  boolean getCrashed(){return crashed;}

  
  void checkCollisions()
  {
    for(int i = 0; i < planetCount; i++)
    {
      Planet planet = (Planet)planets.get(i);
      float distance = sqrt(sq(planet.position.x - position.x) + sq(planet.position.y - position.y));
      if(distance <= planet.rad)
      {
        health = 0;
        crashed = true;
      }
    }
    absorbParticles();
  }

  
  void absorbParticles()
  {
    int count = 0;
    ArrayList<Particle> nearParticles = new ArrayList<Particle>();
    boolean foundParticle = false;
    for (Object o : gameObjects) 
    {
      if (o instanceof Particle) 
      {
        Particle p = (Particle)o;
          float distance = sqrt(sq(p.position.x - position.x) + sq(p.position.y - position.y));
          if(distance < rad)
          {
            foundParticle = true;
            nearParticles.add(p);
            count++;
            if(o.getClass().equals(Health.class))//health particle
            {
              addHealth(50);
            }
            else if(o.getClass().equals(Energy.class))//energy particle
            {
              addEnergy(200);
            }
            else//bullets
            {
              removeHealth(10);
            }
          }
      }
      if (o instanceof Ship)
      {
        Ship e = (Ship)o;
        float distance = sqrt(sq(e.position.x - position.x) + sq(e.position.y - position.y));
        if(distance < (rad + e.rad) && e != this)
          {
          }        
      }
    }
      if(foundParticle)
      {          
        for(Particle o : nearParticles)
        {
          removeGameObject(o);
        }
      }
  }
  
  void applyPlanetGravity()
  {
    super.applyPlanetGravity();
  }
  void turnRight()
  {
    if(alive)
        direction += turnSpeed;
  }
  void turnLeft()
  {
    if(alive)
        direction -= turnSpeed;
  }
  void startFiring()
  {
    firing = true;
  }
  void stopFiring()
  {
    firing = false;
  }
  
  void queueFire()//times the shots so they dont flood out
  {
    if(firingCount == firingDelay)
    {
      firingCount = 0;
      fireBullet();
    }
    else
      firingCount++;
  }
  
  void draw(Camera c)
  {
    if( ((position.x + rad) > c.position.x - (width/2)) && ((position.x - rad) < c.position.x + (width/2)) && ((position.y + rad) > c.position.y - (height/2)) && ((position.y - rad)< c.position.y + (height/2)))
    {
      fill(100,100,100);
      stroke(100,100,100);
      quad((width/2) + (cos(direction + HALF_PI)*20),(height/2) + (sin(direction+ HALF_PI)*20), (width/2) - (cos(direction)*50), (height/2) - (sin(direction)*50),  (width/2) - (cos(direction + HALF_PI)*20), (height/2) - (sin(direction + HALF_PI)*20), (width/2) + (cos(direction)*20), (height/2) + (sin(direction)*20));
    }
  }

  void accelerate()
  {
      velocity.set((velocity.x - cos(direction)*thrustAcc), velocity.y - sin(direction)*thrustAcc, 0);
      velocity.limit(topSpeed);
  }
  void decelerate()
  {
    velocity.set((velocity.x + cos(direction)*thrustAcc), velocity.y + sin(direction)*thrustAcc, 0);
    velocity.limit(topSpeed);
  }
  
    void addHealth(float amount)
    {
      if(health + amount < maxHealth)
        health += amount;
      else
        health = maxHealth; 
    }
    void addEnergy(float amount)
    {
      if(energy + amount < maxEnergy)
        energy += amount;
      else
        energy = maxEnergy;
    }
    void removeHealth(float amount)
    {
      if(health - amount > 0)
        health -= amount;
      else
        health = 0; 
    }
    
    void fireBullet()
    {
      if(energy >= 10)
      {
        PVector newV = new PVector(-cos(direction),-sin(direction),0);
        newV.normalize();
        newV.mult(10);
        newV.add(velocity); //Add the velocity of the ship
        addGameObject(new Bullet((int)(position.x - cos(direction)*2*rad), (int)(position.y - sin(direction)*2*rad), 25, newV));
        particleCount++;
        energy -= 10;
      }
    }
    
    boolean useEnergy(int amount)//if it doesnt have enough energy, it will say so
    {
      if(energy - amount > 0)
      {
        energy -= amount;
        return true;
      }
      return false;  
    }
    
    void checkHealth()
  {
    if(health <=0)
    {
      alive = false;
      drawn = false;
    }
    else
    {
      //alive = true;
    }
  }
  
  void update()
  {

      updatePosition();
      applyPlanetGravity();
      checkCollisions();
      checkHealth();
      if(alive)
      {
        if(firing)
          queueFire();
        else if(firingCount < firingDelay)
          firingCount++; //So the counter keeps going when not shooting and so it "recharges" when not shooting
          
      }
  }

  
  
  
  Ship(int xin, int yin, int massin)
  {
    super(xin, yin, massin);
    thrustAcc = 0.2;
    turnSpeed = 0.07;
    health = 100;
    energy = 1000;
    maxHealth = 100;
    maxEnergy = 1000;
    rad = 20;
    topSpeed = 8;
    mass = 500;
    firingDelay = 4;
    firingCount = 0;
    crashed = false;
    direction =HALF_PI;
  }
}
